package com.zl.iot.docking.service;

import com.aliyun.iot20180120.models.*;
import com.zl.iot.docking.config.ServerInfo;
import com.zl.iot.docking.exception.MyExceptionNew;
import com.zl.iot.docking.exception.ZLExcep;
import com.zl.iot.docking.model.AliServerVO;
import com.zl.iot.docking.util.AliUtil;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zl.iot.docking.consts.AliCode.*;


/**
 * https://help.aliyun.com/product/30520.html
 * https://help.aliyun.com/document_detail/69893.htm?spm=a2c4g.11186623.0.0.5a347792yDTchM#reference-kd4-l4z-wdb
 *
 * @author chenzy
 * @since 2021-11-10
 **/
public class AliServerRequest {
    private static final Logger logger = ServerInfo.getInfoLog();
    private final AliServerVO aliServer;
    private static final Map<String,AliServerRequest> requestMap = new HashMap<>();


    private AliServerRequest(AliServerVO aliServer) {
        this.aliServer = aliServer;
    }


    public static AliServerRequest build(AliServerVO aliServer) {
        var instanceId = AliUtil.getInstanceId(aliServer);
        if (!requestMap.containsKey(instanceId)) {
            requestMap.put(instanceId, new AliServerRequest(aliServer));
        }
        return requestMap.get(instanceId);
    }


    /*创建消费组*/
    public String addConsumerGroup(String consumerGroupName) {
        var instanceId = AliUtil.getInstanceId(aliServer);
        var client = AliUtil.getClient(aliServer);
        try {
            var response = client.createConsumerGroup(new CreateConsumerGroupRequest()
                    .setGroupName(consumerGroupName)
                    .setIotInstanceId(instanceId));
//            logger.info("创建消费组：" + JsonUtil.model2Str(response));
            if (response.body.success) {
                return response.body.groupId;
            }
            switch (response.body.code) {
                case ConsumerGroupNameInvalid:
                    throw ZLExcep.info("消费组名称支持中文汉字、英文字母、数字和下划线（_），长度为4~30个字符，一个汉字计为两个字符");
                case ConsumerGroupNameExisted:
                    /*参考https://next.api.aliyun.com/api/Iot/2018-01-20/QueryConsumerGroupList*/
                    logger.warn("重复添加阿里云消费组");
                    return client.queryConsumerGroupList(new QueryConsumerGroupListRequest()
                                    .setPageSize(1000)
                                    .setCurrentPage(1)
                                    .setGroupName(consumerGroupName)
                                    .setFuzzy(true)
                                    .setIotInstanceId(instanceId)).body.data.consumerGroupDTO.stream()
                            .filter(item -> item.groupName.equals(consumerGroupName))
                            .findFirst()
                            .orElseThrow(() -> ZLExcep.error("未知异常,阿里云说消费组已存在，但调用接口没有找到此消费组"))
                            .groupId;
                case IotInstanceNotFound:
                    throw ZLExcep.info("阿里云说实例不存在,请核查:" + response.body.code);
                default:
                    throw ZLExcep.info("创建消费组异常,没有捕获的阿里云提示:" + response.body.code);
            }
        } catch (MyExceptionNew e) {
            throw e;
        } catch (Exception e) {
            throw ZLExcep.error("创建消费组失败", e);
        }
    }

    /*创建产品*/
    public String addProduct(String name, String msg) {
        var instanceId = AliUtil.getInstanceId(aliServer);
        var client = AliUtil.getClient(aliServer);
        try {
            /*参考https://next.api.aliyun.com/api/Iot/2018-01-20/CreateProduct*/
            var response = client.createProduct(new CreateProductRequest()
                    .setProductName(name)
                    .setNodeType(0)/*0：设备节点*/
                    .setNetType("CELLULAR")/*蜂窝网*/
                    .setAliyunCommodityCode("iothub_senior")/*创建使用物模型的产品*/
                    .setDataFormat(0)/*0：透传/自定义格式*/
                    .setDescription(msg)
                    .setIotInstanceId(instanceId));
//            logger.info("创建产品：" + JsonUtil.model2Str(response));
            if (response.body.success) {
                return response.body.data.productKey;
            }
            switch (response.body.code) {
                case ProductNameInvalidFormatted:
                    throw ZLExcep.info("产品名称长度为4~30个字符，可以包含中文、英文字母、数字和下划线（_）。一个中文算2个字符。");
                case ProductNameAlreadyExisted:
                    logger.warn("重复添加阿里云产品");
                    /*参考https://next.api.aliyun.com/api/Iot/2018-01-20/QueryProductList*/
                    return client.queryProductList(new QueryProductListRequest()
                                    .setIotInstanceId(instanceId)
                                    .setPageSize(200)
                                    .setCurrentPage(1)).body.data.list.productInfo.stream()
                            .filter(item -> item.productName.equals(name))
                            .findFirst()
                            .orElseThrow(() -> ZLExcep.error("未知异常,阿里云说产品已存在，但调用接口没有找到此产品"))
                            .productKey;
                case IotInstanceNotFound:
                    throw ZLExcep.info("阿里云说实例不存在,请核查:" + response.body.code);
                default:
                    throw ZLExcep.info("创建产品异常,没有捕获的阿里云提示:" + response.body.code);
            }
        } catch (MyExceptionNew e) {
            throw e;
        } catch (Exception e) {
            throw ZLExcep.error("创建产品失败", e);
        }

    }

    /*创建消费者-产品订阅关系*/
    public void addSubscribeRelation(String ckey, String consumerGroupId) {
        var instanceId = AliUtil.getInstanceId(aliServer);
        try {
            /*参考https://next.api.aliyun.com/api/Iot/2018-01-20/CreateSubscribeRelation*/
            var type = "AMQP";
            var response = AliUtil.getClient(aliServer).createSubscribeRelation(new CreateSubscribeRelationRequest()
                    .setProductKey(ckey)
                    .setDeviceDataFlag(true)/*推送消息类型选择设备上报消息*/
                    .setDeviceStatusChangeFlag(true)/*推送设备状态改变消息*/
                    .setType(type)
                    .setConsumerGroupIds(List.of(consumerGroupId))
                    .setIotInstanceId(instanceId));
//            logger.info("创建产品-消费组订阅关系：" + JsonUtil.model2Str(response));
            if (response.body.success) {
                return;
            }
            switch (response.body.code) {
                case SubscribeExist:
                    logger.warn("重复添加阿里云产品-消费组订阅");
                    /*订阅已存在*/
                    return;
                case IotInstanceNotFound:
                    throw ZLExcep.info("阿里云说实例不存在,请核查:" + response.body.code);
                case GrantNo:
                    throw ZLExcep.info("阿里云说没有权限操作,请核查:" + response.body.errorMessage);
                case ConsumerGroupInvalid:
                    throw ZLExcep.info("阿里云说消费组不存在,请核查:" + response.body.code);
                case SubscribeTypeInvalid:
                    throw ZLExcep.info("订阅类型" + type + "无效:" + response.body.errorMessage);
                default:
                    throw ZLExcep.info("创建产品-消费组订阅关系,没有捕获的阿里云提示:" + response.body.code);
            }
        } catch (MyExceptionNew e) {
            throw e;
        } catch (Exception e) {
            throw ZLExcep.error("创建产品-消费组订阅关系失败", e);
        }
    }

}
